package com.openlogic.flow.controller;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dromara.warm.flow.core.entity.Definition;
import org.dromara.warm.flow.core.enums.PublishStatus;
import org.dromara.warm.flow.core.service.ChartService;
import org.dromara.warm.flow.core.service.DefService;
import org.dromara.warm.flow.orm.entity.FlowDefinition;
import org.noear.solon.annotation.Body;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Delete;
import org.noear.solon.annotation.Get;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.annotation.Path;
import org.noear.solon.annotation.Post;
import org.noear.solon.annotation.Put;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Result;
import org.noear.solon.core.handle.UploadedFile;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.openlogic.common.core.enums.BusinessType;
import com.openlogic.common.core.web.controller.BaseController;
import com.openlogic.common.core.web.domain.PageData;
import com.openlogic.common.datasource.annotation.QzLog;
import com.openlogic.flow.domain.query.FlowDefinitionQuery;
import com.openlogic.flow.service.IFlowDefinitionServcie;

/**
 * @ClassName: FlowDefinitionController
 * @Description: 流程定义Controller
 * @author weiyongpeng
 * @date 2025年2月10日 下午2:31:51
 */
@Controller
@Mapping("flow/definition")
public class FlowDefinitionController extends BaseController {

	@Inject
	DefService defService;
	
	@Inject
	ChartService chartService;
	
	@Inject
	IFlowDefinitionServcie flowDefinitionServcie;
	
	/**
	 * 描述：查询流程定义列表
	 * @Title: list
	 * @param page
	 * @param flowDefinitionQuery
	 * @return
	 * @author weiyongpeng
	 * @date 2025年2月12日 下午4:18:49
	 */
	@QzLog(title = "流程定义列表-已发布", businessType = BusinessType.LIST)
	@Get
	@Mapping("/list")
    public PageData<FlowDefinition> list(Page<FlowDefinition> page, FlowDefinitionQuery flowDefinitionQuery) {
		QueryWrapper qw = getQW(flowDefinitionQuery);
		// 已发布
        qw.eq(FlowDefinition::getIsPublish, PublishStatus.PUBLISHED.getKey());
		Page<FlowDefinition> pageList = flowDefinitionServcie.page(page, qw);
        return getPageData(pageList);
    }
	
	
	/**
	* 描述：查询未发布流程定义列表
	* @Title: unPublishList
	* @param page
	* @param flowDefinitionQuery
	* @return
	* @author weiyongpeng
	* @date  2025年2月12日 下午8:47:49
	 */
	@QzLog(title = "流程定义列表-未发布", businessType = BusinessType.LIST)
	@Get
	@Mapping("/unPublishList")
    public PageData<FlowDefinition> unPublishList(Page<FlowDefinition> page, FlowDefinitionQuery flowDefinitionQuery) {
		QueryWrapper qw = getQW(flowDefinitionQuery);
		// 未发布
		qw.in(FlowDefinition::getIsPublish, Arrays.asList(PublishStatus.UNPUBLISHED.getKey(), PublishStatus.EXPIRED.getKey()));
		Page<FlowDefinition> pageList = flowDefinitionServcie.page(page, qw);
        return getPageData(pageList);
    }
	
    /**
    * 描述：获取流程定义详细信息
    * @Title: getInfo
    * @param id
    * @return
    * @author weiyongpeng
    * @date  2025年2月12日 下午4:19:00
     */
	@QzLog(title = "流程定义详细信息", businessType = BusinessType.LIST)
	@Get
    @Mapping(value = "/{id}")
    public Result<Definition> getInfo(@Path Long id) {
        return Result.succeed(defService.getById(id));
    }

	/**
	 * 描述：新增流程定义
	 * @Title: add
	 * @param flowDefinition
	 * @return
	 * @author weiyongpeng
	 * @date 2025年2月10日 下午7:40:10
	 */
	@QzLog(title = "流程定义新增", businessType = BusinessType.INSERT)
	@Post
	@Mapping
	public Result<Boolean> add(@Body FlowDefinition flowDefinition) {
		return Result.succeed(defService.checkAndSave(flowDefinition));
	}

	/**
	* 描述：修改流程定义
	* @Title: edit
	* @param flowDefinition
	* @return
	* @author weiyongpeng
	* @date  2025年2月10日 下午7:40:22
	 */
	@QzLog(title = "流程定义修改", businessType = BusinessType.UPDATE)
	@Put
	@Mapping
	public Result<Boolean> edit(@Body FlowDefinition flowDefinition) {
		return Result.succeed(defService.updateById(flowDefinition));
	}
	
    /**
    * 描述：导入流程定义
    * @Title: importDef
    * @param file json文件
    * @param category 流程类别id
    * @return
    * @author weiyongpeng
    * @date  2025年2月12日 下午7:58:47
     */
	@QzLog(title = "流程定义", businessType = BusinessType.IMPORT)
	@Post
    @Mapping("importDef/{category}")
    public Result<Boolean> importDef(@Body UploadedFile file,@Path String category) {
        return Result.succeed(flowDefinitionServcie.importJson(file, category));
    }
	
    /**
    * 描述：导出流程定义json 
    * @Title: exportDef
    * @param id 流程定义id
    * @param ctx 请求上下文
    * @throws IOException
    * @author weiyongpeng
    * @date  2025年2月12日 下午8:23:47
     */
	@QzLog(title = "流程定义", businessType = BusinessType.EXPORT)
	@Post
    @Mapping("exportDef/{id}")
    public void exportDef(@Path Long id, Context ctx) throws IOException {
		flowDefinitionServcie.exportDef(id, ctx);
    }
	
    /**
    * 描述：查询流程图-流程定义
    * @Title: chartDef
    * @param definitionId 流程定义id
    * @return
    * @author weiyongpeng
    * @date  2025年2月12日 下午8:56:32
     */
	@Get
    @Mapping("/chartDef/{definitionId}")
    public Result<Map<String, Object>> chartDef(@Path("definitionId") Long definitionId) {
		HashMap<String, Object> resMap = new HashMap<>();
		resMap.put("img", chartService.chartDef(definitionId));
        return Result.succeed(resMap);
    }
	
	/**
	 * 描述：查询流程图-流程实例
	 * @Title: chartFlowIns
	 * @param insId 流程实例id
	 * @return
	 * @author weiyongpeng
	 * @date 2025年2月12日 下午8:56:32
	 */
	@QzLog(title = "查看流程图-流程实例", businessType = BusinessType.LIST)
	@Get
	@Mapping("/chartFlowIns/{insId}")
	public Result<String> chartFlowIns(@Path("insId") Long insId) {
		return Result.succeed(chartService.chartIns(insId));
	}

	/**
	* 描述：发布流程定义
	* @Title: publish
	* @param id 流程定义id
	* @return
	* @author weiyongpeng
	* @date  2025年2月11日 下午7:28:50
	 */
	@QzLog(title = "流程定义发布", businessType = BusinessType.INSERT)
	@Put
	@Mapping("publish/{id}")
	public Result<Boolean> publish(@Path Long id) {
		return Result.succeed(flowDefinitionServcie.publish(id));
	}

	/**
	* 描述：取消发布流程定义
	* @Title: unPublish
	* @param id 流程定义id
	* @return
	* @author weiyongpeng
	* @date  2025年2月11日 下午7:28:33
	 */
	@QzLog(title = "流程定义取消发布", businessType = BusinessType.INSERT)
	@Put
	@Mapping("unPublish/{id}")
	public Result<Boolean> unPublish(@Path Long id) {
		return Result.succeed(defService.unPublish(id));
	}
	
	/**
	* 描述：激活/挂起流程定义
	* @Title: active
	* @param id 流程定义id
	* @param active true激活；false挂起
	* @return
	* @author weiyongpeng
	* @date  2025年2月12日 下午8:41:50
	 */
	@QzLog(title = "激活/挂起流程定义", businessType = BusinessType.INSERT)
	@Put
    @Mapping("active/{id}")
    public Result<Boolean> active(@Path Long id, @Param boolean active) {
		return Result.succeed(active ? defService.active(id) : defService.unActive(id));
    }

	/**
	* 描述：删除流程定义
	* @Title: remove
	* @param ids 流程定义id 多个用逗号分割 list
	* @return
	* @author weiyongpeng
	* @date  2025年2月11日 下午7:26:12
	 */
    @QzLog(title = "流程定义删除", businessType = BusinessType.DELETE)
    @Delete
    @Mapping("{ids}")
    public Result<Boolean> remove(@Path List<Long> ids) {
        return Result.succeed(flowDefinitionServcie.removeDef(ids));
    }

	/**
	* 描述：复制流程定义
	* @Title: copy
	* @param id
	* @return
	* @author weiyongpeng
	* @date  2025年2月10日 下午7:40:53
	 */
	@QzLog(title = "流程定义复制", businessType = BusinessType.INSERT)
	@Post
	@Mapping("copy/{id}")
	public Result<Boolean> copy(@Path Long id) {
		return Result.succeed(defService.copyDef(id));
	}

	/**
	* 描述：构建查询条件
	* @Title: getQW
	* @param flowDefinitionQuery
	* @return
	* @author weiyongpeng
	* @date  2025年2月12日 下午8:34:58
	 */
	private QueryWrapper getQW(FlowDefinitionQuery flowDefinitionQuery) {
        QueryWrapper qw = QueryWrapper.create();
        return qw;
    }
}
